/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import org.aswing.ASColor;
import org.aswing.BorderLayout;
import org.aswing.JMenuItem;
import org.aswing.JPanel;
import org.aswing.JSeparator;

import com.bourre.commands.Delegate;
import com.bourre.events.BasicEvent;

import fever.app.accelerator.Keyboard;
import fever.app.accelerator.KeyCombo;
import fever.app.local.LocalisationEvent;
import fever.data.file.FileFilter;
import fever.Fever;
import fever.utils.DateUtils;

import fvaswing.components.menu.FvMenu;
import fvaswing.components.menu.FvMenuItem;
import fvaswing.components.reader.abstract.FvReader;
import fvaswing.components.reader.abstract.FvReaderEvent;
import fvaswing.components.reader.video.FvBasicVideoUI;
import fvaswing.components.reader.video.FvVideoBookmark;
import fvaswing.components.reader.video.FvVideoDocument;
import fvaswing.components.reader.video.FvVideoDocumentListener;
import fvaswing.components.reader.video.FvVideoItem;
import fvaswing.components.reader.video.FvVideoList;
import fvaswing.components.reader.video.FvVideoMarker;
import fvaswing.FvAsWing;

/**
 * Display and manage medias document ( flv and mp3 files )
 * 
 * <p>Don't forget to add :
 * {@code
 *   mySWFObject.addParam( "allowFullScreen", "true" );
 * }
 * in your html document to allow fullscreen mode.
 * 
 * <p>SWF file must have a embeded movieclip named "VideoDisplay" 
 * with a Video object named "video".<br />
 * Example using swfmill
 * {@code
 *   <clip id="VideoDisplay" name="VideoDisplay">
 *       <frame>
 *   		<video id="vid" width="320" height="240" x="0" y="0" />
 *   		<place id="vid" name="video" />
 *   	</frame>
 *   </clip>
 * 
 * }
 * 
 * @author Romain Ecarnot
 */
class fvaswing.components.reader.FvVideoPlayer extends FvReader
{
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private static var _instance : FvVideoPlayer;
	
	private var _controlbar : JPanel;
	
	private var _playItemMenu : FvMenuItem;
	private var _stopItemMenu : JMenuItem;
	private var _fullItemMenu : FvMenuItem;
	
	private var _volumeMenu : FvMenu;
	private var _incVolItemMenu : FvMenuItem;
	private var _decVolItemMenu : FvMenuItem;
	private var _muteVolItemMenu : JMenuItem;
	private var _storedTitle : String;
	
	private var _bookmark : FvVideoBookmark;
	private var _ui;
	
	private var _interval : Number;
	
	
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Returns unique {@link FvVideoPlayer} instance.
	 */
	public static function getInstance( enabledExternalLoading : Boolean ) : FvVideoPlayer
	{
		if( _instance ) _instance = new FvVideoPlayer( 'videoplayer', enabledExternalLoading );
		return _instance;
	}
	
	/**
	 * Constructor.
	 */
	public function FvVideoPlayer( name : String, enabledExternalLoading : Boolean )
	{
		super( name, enabledExternalLoading );
		
		delete _loader;
	}
	
	/**
	 * Returns current {@link fvaswing.components.reader.video.FvVideoDocument} 
	 * instance.
	 */
	public function getDocumentManager() : FvVideoDocument
	{
		return FvVideoDocument( _document );
	}
	
	/**
	 * Adds passed-in {@link fvaswing.components.reader.video.FvVideoItem} 
	 * to reader list.
	 */
	public function addDocument( doc : FvVideoItem ) : Void
	{
		_list.addDocument( doc );
	}
	
	/**
	 * Removes passed-in {@link fvaswing.components.reader.video.FvVideoItem} 
	 * from reader list.
	 */
	public function removeDocument( doc : FvVideoItem ) : Void
	{
		_list.removeDocument( doc );
	}
	
	/**
	 * Triggered when Localisation language change.
	 */
	public function onLocalisationUpdate( event : LocalisationEvent ) : Void
	{
		super.onLocalisationUpdate( event );
		
		_playItemMenu.setText( _resource.videoPlay );
		_stopItemMenu.setText( _resource.videoStop );
		_fullItemMenu.setText( _resource.videoFull );
		
		_volumeMenu.setText( _resource.videoVolume );
		_incVolItemMenu.setText( _resource.videoIncrease );		_decVolItemMenu.setText( _resource.videoDecrease );		_muteVolItemMenu.setText( _resource.videoMute );
	}
	
	/**
	 * Sets the controller bar UI.
	 */
	public function setVideoUIControl( ui : FvVideoDocumentListener ) : Void
	{
		if( ui != _ui )
		{ 
			if( getDocumentManager() != undefined )
			{
				getDocumentManager().removeListener( _ui );
				_controlbar.remove( _ui );
				
				_ui = ui;
				getDocumentManager().addListener( _ui );
				_controlbar.append( _ui, BorderLayout.CENTER );
			}
			else _ui = ui;
		} 
	}
	
	/**
	 * Returns the controller bar UI.
	 */
	public function getVideoUIControl() : FvVideoDocumentListener 
	{
		return _ui;
	}
	
	/**
	 * No loader in {@link FvVideoPlayer}
	 */
	public function setLoaderUI() : Void
	{
		// do nothing
	}
	
	/**
	 * No loader in {@link FvVideoPlayer}
	 */
	public function getLoaderUI() : Void
	{
		// do nothing	
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	private function _parseNewPlayList( o : Object, url : String ) : Void
	{
		if( o.videos != "" )
		{
			_getPlayList().removeAllDocument();
			_xmlListFile = url;
			
			var l : Number = o.videos.item.length;
			
			for( var i : Number = 0; i < l; i++ )
			{
				var x : Object = o.videos.item[i];
				var item : FvVideoItem = new FvVideoItem( x.url, x.title, x.phpStreaming );
				
				item.setBookmark( x.bookmark );
				addDocument( item );
			}
		}
		else
		{
			Fever.dialog.alert( url + _resource.alertList );
		}
		
		_lockInteraction( false );
	}
	
	/**
	 * Overrides for custom playlist class
	 */
	private function _getPlayList() : FvVideoList
	{
		return new FvVideoList( _name, _enabledExternalFile );
	}
	
	/**
	 * Overrides for custom bookmark class
	 */
	private function _getBookmark() : FvVideoBookmark
	{
		return 	new FvVideoBookmark( _mainContainer );
	}
	
	private function _configure() : Void
	{
		super._configure();
		
		_bookmark = _getBookmark();
		_bookmark.addEventListener( FvVideoBookmark.onBookmarkResizeEVENT, this, onBookmarkResize );		_bookmark.addEventListener( FvVideoBookmark.onMarkerEVENT, this, onBookmarkMarker );
		
		_mainContainer.append (_bookmark.getView(), BorderLayout.EAST );
	}
	
	private function onBookmarkResize( event : BasicEvent ) : Void
	{
		_mainContainer.revalidateIfNecessary();	
	}
	
	private function onBookmarkMarker( event : BasicEvent ) : Void
	{
		getDocumentManager().seek( FvVideoMarker( event.getTarget() ).time );	
	}
	
	private function _configureChooser() : Void
	{
		super._configureChooser();
		
		_fileChooser.addChoosableFileFilter( FileFilter.getFlashVideoFilter() );
		_fileChooser.setAcceptAllFileFilterUsed( false );
	}
	
	private function _createDocumentPanel() : JPanel
	{
		_controlbar = new JPanel( new BorderLayout( 5,5 ) );
		setVideoUIControl( new FvBasicVideoUI() );
		
		_documentContainer = new JPanel( new BorderLayout( 5, 5 ) );
		_documentContainer.setOpaque( true );
		_documentContainer.setBackground( ASColor.BLACK );
		_documentContainer.addEventListener( JPanel.ON_CREATED, _onPanelCreated, this );
		_documentContainer.addEventListener( JPanel.ON_RESIZED, _handleResizing, this );
		
		var p : JPanel = new JPanel( new BorderLayout( 5,5 ) );
		p.append( _controlbar, BorderLayout.SOUTH );
		p.append( _documentContainer, BorderLayout.CENTER );
		return p;
	}
	
	private function _onPanelCreated( source : JPanel ) : Void
	{
		_loaderView = _documentContainer.createMovieClip( "_lv_" );
		_target = _documentContainer.createMovieClip( "_vt_" );
		
		_initDocumentManager( new FvVideoDocument( this, _target ) );
		
		getDocumentManager().addEventListener( FvVideoDocument.onMetaDataEVENT, this,_update );
		getDocumentManager().addEventListener( FvVideoDocument.onFullScreenEVENT, this,_onFullScreenMode );		getDocumentManager().addListener( _ui );
		
		_controlbar.append( _ui, BorderLayout.CENTER );	
		
		if( _pendingLoad )
		{
			_pendingLoad = false;
			_document.load( _pendingItem );
		}
	}
	
	private function _update( event : FvReaderEvent ) : Void
	{
		var item : FvVideoItem = getDocumentManager().getDocument();
		
		_handleResizing();
		_bookmark.loadBookmark( item.getBookmark() );
		
		_list.updateDocument( item );
		_frame.setTitle( item.getTitle() );
		_storedTitle = item.getTitle();
		
		clearInterval( _interval );
		_interval = setInterval( this, "_changeFrameTitle", 1000 );
		_changeFrameTitle();
	}
	
	private function _changeFrameTitle() : Void
	{
		var t : String = DateUtils.seconde2time( getDocumentManager().getPlayHeadTime() );
		
		_frame.setTitle( _storedTitle + " ( " + t + " )" );
	}
	
	
	//-------------------------------------------------------------------------
	// Menubar
	//-------------------------------------------------------------------------
	
	/**
	 * Custom document menu
	 */
	private function _getDocumentMenu() : FvMenu
	{
		_docMenu = new FvMenu( _resource.docMenuLabel );
		_docMenu.setEnabled( false );
		
		_playItemMenu = _docMenu.addMenuItem( _resource.videoPlay, _handlePlayPause, this, new KeyCombo( Keyboard.onKeyCONTROL, Keyboard.onKeyP ) );
		_keyMap.registerCustomType( FvAsWing.AWSHORTCUT, _playItemMenu.getShortCut(), _playItemMenu );
		
		_stopItemMenu = _docMenu.addMenuItem( _resource.videoStop );
		_stopItemMenu.addActionListener( Delegate.create( this, _handleStop ) );
		
		_volumeMenu = new FvMenu( _resource.videoVolume );
		
		_incVolItemMenu = _volumeMenu.addMenuItem( _resource.videoIncrease, _handleIncreaseVolume, this, Keyboard.onKeyADD );
		_keyMap.registerCustomType( FvAsWing.AWSHORTCUT, _incVolItemMenu.getShortCut(), _incVolItemMenu );
		
		_decVolItemMenu = _volumeMenu.addMenuItem( _resource.videoDecrease, _handleDecreaseVolume, this, Keyboard.onKeySUBSTRACT );
		_keyMap.registerCustomType( FvAsWing.AWSHORTCUT, _decVolItemMenu.getShortCut(), _decVolItemMenu );
		
		_muteVolItemMenu = _volumeMenu.addMenuItem( _resource.videoMute );
		_muteVolItemMenu.addActionListener( Delegate.create( this, _handleMuteVolume ) );
		
		_docMenu.append( _volumeMenu );
		
		_docMenu.append( new JSeparator( JSeparator.HORIZONTAL ) );
		
		_fullItemMenu = _docMenu.addMenuItem( _resource.videoFull, _handleFullscreen, this, new KeyCombo( Keyboard.onKeyCONTROL, Keyboard.onKeyF ) );
		_keyMap.registerCustomType( FvAsWing.AWSHORTCUT, _fullItemMenu.getShortCut(), _fullItemMenu );
		
		return _docMenu;
	}
	
	private function _handlePlayPause( source : FvMenuItem ) : Void
	{
		getDocumentManager().toggle();
	}
	
	private function _handleStop( source : JMenuItem ) : Void
	{
		getDocumentManager().stop();
	}
	
	private function _handleFullscreen( source : FvMenuItem ) : Void
	{
		_frame.setActive( false );
		getDocumentManager().openFullScreen();
	}
	
	private function _handleIncreaseVolume( source : FvMenuItem ) : Void
	{
		getDocumentManager().appendVolume( 10 );
	}
	
	private function _handleDecreaseVolume( source : FvMenuItem ) : Void
	{
		getDocumentManager().appendVolume( -10 );
	}
	
	private function _handleMuteVolume( source : JMenuItem ) : Void
	{
		getDocumentManager().mute();	
	}
	
	private function _onFullScreenMode( event : FvReaderEvent ) : Void
	{
		_frame.setActive( !Fever.application.isFullScreen() );	
	}
}